package com.mobile.tools.cfg;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.hibernate.mapping.Column;
import org.hibernate.mapping.Property;
import org.hibernate.type.Type;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

import com.mobile.tools.CopyFile;
import com.mobile.tools.FieldInfo;
import com.mobile.tools.XMLUtil;
/**
 * hbm.xml文件的管理工具类
 * @author huangfeng
 *
 */
public class HbmXMLManageUtil {
	/**
	 * 创建xml的属性的对象
	 * @param document
	 * @param property
	 * @return
	 */
	private static Element creatPropertyElement(Document document,Property property){
		Element element=document.createElement("property");
		Type type=property.getType();
		
		element.setAttribute("name", property.getName());
		element.setAttribute("column", ((Column)property.getColumnIterator().next()).getName());
		element.setAttribute("type", type.getReturnedClass().getName());
		element.setAttribute("not-null", String.valueOf(false));
		
		return element;
	}
	/**
	 * 创建xml的属性的对象
	 * @param document
	 * @param map
	 * @return
	 */
	private static Element creatPropertyElement(Document document,Map<String,String> map){
		Element element=document.createElement("property");
		
		element.setAttribute("name", map.get("name"));
		element.setAttribute("column", map.get("column"));
		element.setAttribute("type", map.get("type"));
		element.setAttribute("not-null", String.valueOf(false));
		
		return element;
	}
	/**
	 * 创建xml的属性的对象
	 * @param document
	 * @param map
	 * @return
	 */
	private static Element creatPropertyElement(Document document,FieldInfo fieldInfo){
		Element element=document.createElement("property");
		
		element.setAttribute("name", fieldInfo.getFieldName());
		element.setAttribute("column", fieldInfo.getFieldName());
		element.setAttribute("type", fieldInfo.getFieldType().getName());
		element.setAttribute("not-null", String.valueOf(false));
		
		return element;
	}
	/**
	 * 创建xml的属性的对象
	 * @param document		文档实体
	 * @param node			节点
	 * @param collection	字段集
	 * @return
	 */
	private static void creatPropertyElement(Document document,Node node,Collection<FieldInfo> collection){
		for(FieldInfo fieldInfo : collection){
			Element element=creatPropertyElement(document,fieldInfo);
			node.appendChild(element);
		}
	}
	/**
	 * 更新映射文件
	 * @param collection		修改文件的基本数据信息
	 */
	public static void updateDynamicComponent(String hbmXmlPath,Collection<FieldInfo> collection){

		try {
			Document document=XMLUtil.loadDocument(hbmXmlPath);
			
			updateDynamicComponent(document, hbmXmlPath, collection);
			
			XMLUtil.saveDocument(document, hbmXmlPath);
		} catch (DOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch(TransformerException e){
			e.printStackTrace();
		}
	}
	private static void updateDynamicComponent(Document document,String hbmXmlPath,Collection<FieldInfo> collection){
		NodeList componentTags=document.getElementsByTagName("dynamic-component");
		Node node=componentTags.item(0);
		XMLUtil.removeChildren(node);
		
		creatPropertyElement(document, node, collection);
	}
	/**
	 * 修改映射文件的实体名和表名
	 * @param mappingName
	 * @param entityName
	 */
	public static void updateEntityName(String hbmXmlPath,String entityName){
		try {
			Document document=XMLUtil.loadDocument(hbmXmlPath);
			updateEntityName(document, hbmXmlPath, entityName);
			XMLUtil.saveDocument(document, hbmXmlPath);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e){
			e.printStackTrace();
		}
		
	}
	/**
	 * 修改映射文件的实体名和表名
	 * @param document		文档实体		
	 * @param mappingName	映射文件名
	 * @param entityName	实体名
	 */
	private static void updateEntityName(Document document,String hbmXmlPath,String entityName){
		NodeList nodeList=document.getElementsByTagName("class");
		Element element=(Element)nodeList.item(0);
		element.setAttribute("entity-name",entityName);
		element.setAttribute("table", entityName);
		nodeList=document.getElementsByTagName("param");
		Element elementParam=(Element)nodeList.item(0);
		XMLUtil.removeChildren(elementParam);
		Text text=document.createTextNode(entityName+"_SEQ");
		elementParam.appendChild(text);	
	}
	/**
	 * 复制hbm.xml文件
	 * @param newHbmFilePath		目标文件
	 * @param sourceHbmFilePath	源文件
	 */
	public static void copyHbmXML(String newHbmFilePath,String sourceHbmFilePath){
		CopyFile.copyFile(new File(newHbmFilePath), new File(sourceHbmFilePath));
	}
	/**
	 * 复制hbm.xml文件,并添加字段信息
	 * @param newHbmFilePath		目标文件
	 * @param sourceHbmFilePath	源文件
	 * @param collection		字段信息集
	 */
	public static void copyHbmXML(String newHbmFilePath,String sourceHbmFilePath,Collection<FieldInfo> collection,String entityName){
		copyHbmXML(newHbmFilePath, sourceHbmFilePath);
		try {
			Document document=XMLUtil.loadDocument(newHbmFilePath);
			updateEntityName(document, newHbmFilePath, entityName);
			updateDynamicComponent(document, newHbmFilePath, collection);
			XMLUtil.saveDocument(document, newHbmFilePath);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e){
			e.printStackTrace();
		}
		
	}
}
